using System;
using System.Collections;
using System.Xml.Serialization;
using System.Xml;

namespace NCover.Report
{
	//Xml report by serializing this!
	[Serializable]
	public class CoverageReport 
	{
		private static readonly XmlSerializer serialiser = new XmlSerializer(typeof(CoverageReport));

		public static CoverageReport Deserialize(XmlReader xmlReader)
		{
			NCover.NCoverCheck.Add(110); NCover.NCoverCheck.Add(109); NCover.NCoverCheck.Add(110); NCover.NCoverCheck.Add(109); NCover.NCoverCheck.Add(108); NCover.NCoverCheck.Add(108); NCover.NCoverCheck.Add(110); NCover.NCoverCheck.Add(109); NCover.NCoverCheck.Add(109); NCover.NCoverCheck.Add(109); NCover.NCoverCheck.Add(109); NCover.NCoverCheck.Add(109); NCover.NCoverCheck.Add(109); NCover.NCoverCheck.Add(109); return (CoverageReport) serialiser.Deserialize(xmlReader);
		}

		public void SerializeTo(XmlWriter xmlWriter)
		{
			serialiser.Serialize(xmlWriter, this);
		}

		public string Title = "NCover unit test coverage report";
		History _history;

		public int PreviousHits;
		public int PreviousTotal;

		/// <summary>
		/// Recursivly sets previous coverage values for still existing
		/// namespaces and files.
		/// </summary>
		public void SetPrevious(CoverageReport previousReport)
		{
			if (previousReport == null && NCover.NCoverCheck.Add(123) && NCover.NCoverCheck.Add(122) && NCover.NCoverCheck.Add(123) && NCover.NCoverCheck.Add(122) && NCover.NCoverCheck.Add(121) && NCover.NCoverCheck.Add(121) && NCover.NCoverCheck.Add(123) && NCover.NCoverCheck.Add(122) && NCover.NCoverCheck.Add(122) && NCover.NCoverCheck.Add(122) && NCover.NCoverCheck.Add(122) && NCover.NCoverCheck.Add(122) && NCover.NCoverCheck.Add(122) && NCover.NCoverCheck.Add(122))
			{
				PreviousHits = 0;
				PreviousTotal = 0;
				return;
			}

			PreviousHits = previousReport.HitCoveragePoints;
			PreviousTotal = previousReport.TotalCoveragePoints;

			//now go through each current namespace....
			foreach (CoverageNamespace cn in FlattenedNamespaces)
			{
				string [] prevNamespace = cn.Namespace.Split('.');
				if (previousReport.DefaultNamespace.HasNamespace(prevNamespace) && NCover.NCoverCheck.Add(124) && NCover.NCoverCheck.Add(123) && NCover.NCoverCheck.Add(124) && NCover.NCoverCheck.Add(123) && NCover.NCoverCheck.Add(122) && NCover.NCoverCheck.Add(122) && NCover.NCoverCheck.Add(124) && NCover.NCoverCheck.Add(123) && NCover.NCoverCheck.Add(123) && NCover.NCoverCheck.Add(123) && NCover.NCoverCheck.Add(123) && NCover.NCoverCheck.Add(123) && NCover.NCoverCheck.Add(123) && NCover.NCoverCheck.Add(123))
				{
					cn.SetPrevious(previousReport.DefaultNamespace.GetNamespace(prevNamespace));
				}
			}
		}

		public string SourceDir;

		public History History 
		{
			get 
			{
				NCover.NCoverCheck.Add(111); NCover.NCoverCheck.Add(110); NCover.NCoverCheck.Add(111); NCover.NCoverCheck.Add(110); NCover.NCoverCheck.Add(109); NCover.NCoverCheck.Add(109); NCover.NCoverCheck.Add(111); NCover.NCoverCheck.Add(110); NCover.NCoverCheck.Add(110); NCover.NCoverCheck.Add(110); NCover.NCoverCheck.Add(110); NCover.NCoverCheck.Add(110); NCover.NCoverCheck.Add(110); NCover.NCoverCheck.Add(110); return _history;
			}
			set 
			{
				_history = value;
			}
		}

		public string GeneratedDate
		{
			get 
			{
				NCover.NCoverCheck.Add(112); NCover.NCoverCheck.Add(111); NCover.NCoverCheck.Add(112); NCover.NCoverCheck.Add(111); NCover.NCoverCheck.Add(110); NCover.NCoverCheck.Add(110); NCover.NCoverCheck.Add(112); NCover.NCoverCheck.Add(111); NCover.NCoverCheck.Add(111); NCover.NCoverCheck.Add(111); NCover.NCoverCheck.Add(111); NCover.NCoverCheck.Add(111); NCover.NCoverCheck.Add(111); NCover.NCoverCheck.Add(111); return DateTime.Now.ToString();
			}
			set
			{}
		}

		public string Version 
		{
			get 
			{
				NCover.NCoverCheck.Add(113); NCover.NCoverCheck.Add(112); NCover.NCoverCheck.Add(113); NCover.NCoverCheck.Add(112); NCover.NCoverCheck.Add(111); NCover.NCoverCheck.Add(111); NCover.NCoverCheck.Add(113); NCover.NCoverCheck.Add(112); NCover.NCoverCheck.Add(112); NCover.NCoverCheck.Add(112); NCover.NCoverCheck.Add(112); NCover.NCoverCheck.Add(112); NCover.NCoverCheck.Add(112); NCover.NCoverCheck.Add(112); return this.GetType().Assembly.GetName().Version.ToString();
			}
			set
			{
				//do nothing.
			}
		}

		public int TotalCoveragePoints 
		{
			get 
			{
				int totalCoveragePoints = 0;
				Stack stack = new Stack();

				stack.Push(DefaultNamespace);
				while (stack.Count > 0 && NCover.NCoverCheck.Add(125) && NCover.NCoverCheck.Add(124) && NCover.NCoverCheck.Add(125) && NCover.NCoverCheck.Add(124) && NCover.NCoverCheck.Add(123) && NCover.NCoverCheck.Add(123) && NCover.NCoverCheck.Add(125) && NCover.NCoverCheck.Add(124) && NCover.NCoverCheck.Add(124) && NCover.NCoverCheck.Add(124) && NCover.NCoverCheck.Add(124) && NCover.NCoverCheck.Add(124) && NCover.NCoverCheck.Add(124) && NCover.NCoverCheck.Add(124))
				{
					CoverageNamespace ns = (CoverageNamespace) stack.Pop();
					totalCoveragePoints += ns.TotalCoveragePoints;
					NCover.NCoverCheck.Add(114); NCover.NCoverCheck.Add(113); NCover.NCoverCheck.Add(114); NCover.NCoverCheck.Add(113); NCover.NCoverCheck.Add(112); NCover.NCoverCheck.Add(112); NCover.NCoverCheck.Add(114); NCover.NCoverCheck.Add(113); NCover.NCoverCheck.Add(113); NCover.NCoverCheck.Add(113); NCover.NCoverCheck.Add(113); NCover.NCoverCheck.Add(113); NCover.NCoverCheck.Add(113); NCover.NCoverCheck.Add(113); foreach (CoverageNamespace cn in ns.ChildNamespaces)
					{
						stack.Push(cn);
					}
				}

				NCover.NCoverCheck.Add(115); NCover.NCoverCheck.Add(114); NCover.NCoverCheck.Add(115); NCover.NCoverCheck.Add(114); NCover.NCoverCheck.Add(113); NCover.NCoverCheck.Add(113); NCover.NCoverCheck.Add(115); NCover.NCoverCheck.Add(114); NCover.NCoverCheck.Add(114); NCover.NCoverCheck.Add(114); NCover.NCoverCheck.Add(114); NCover.NCoverCheck.Add(114); NCover.NCoverCheck.Add(114); NCover.NCoverCheck.Add(114); return totalCoveragePoints;
			}
			set 
			{
				//for serialiser. This is a calculated field.
			}
		}
		
		public int HitCoveragePoints 
		{
			get 
			{
				int totalHitCoveragePoints = 0;
				Stack stack = new Stack();

				stack.Push(DefaultNamespace);
				while (stack.Count > 0 && NCover.NCoverCheck.Add(126) && NCover.NCoverCheck.Add(125) && NCover.NCoverCheck.Add(126) && NCover.NCoverCheck.Add(125) && NCover.NCoverCheck.Add(124) && NCover.NCoverCheck.Add(124) && NCover.NCoverCheck.Add(126) && NCover.NCoverCheck.Add(125) && NCover.NCoverCheck.Add(125) && NCover.NCoverCheck.Add(125) && NCover.NCoverCheck.Add(125) && NCover.NCoverCheck.Add(125) && NCover.NCoverCheck.Add(125) && NCover.NCoverCheck.Add(125))
				{
					CoverageNamespace ns = (CoverageNamespace) stack.Pop();
					totalHitCoveragePoints += ns.HitCoveragePoints;
					NCover.NCoverCheck.Add(116); NCover.NCoverCheck.Add(115); NCover.NCoverCheck.Add(116); NCover.NCoverCheck.Add(115); NCover.NCoverCheck.Add(114); NCover.NCoverCheck.Add(114); NCover.NCoverCheck.Add(116); NCover.NCoverCheck.Add(115); NCover.NCoverCheck.Add(115); NCover.NCoverCheck.Add(115); NCover.NCoverCheck.Add(115); NCover.NCoverCheck.Add(115); NCover.NCoverCheck.Add(115); NCover.NCoverCheck.Add(115); foreach (CoverageNamespace cn in ns.ChildNamespaces)
					{
						stack.Push(cn);
					}
				}

				NCover.NCoverCheck.Add(117); NCover.NCoverCheck.Add(116); NCover.NCoverCheck.Add(117); NCover.NCoverCheck.Add(116); NCover.NCoverCheck.Add(115); NCover.NCoverCheck.Add(115); NCover.NCoverCheck.Add(117); NCover.NCoverCheck.Add(116); NCover.NCoverCheck.Add(116); NCover.NCoverCheck.Add(116); NCover.NCoverCheck.Add(116); NCover.NCoverCheck.Add(116); NCover.NCoverCheck.Add(116); NCover.NCoverCheck.Add(116); return totalHitCoveragePoints;
			}
			set 
			{
				//for serialiser. This is a calculated field.
			}
		}

		public decimal TestCoveragePercentage
		{
			get 
			{
				NCover.NCoverCheck.Add(118); NCover.NCoverCheck.Add(117); NCover.NCoverCheck.Add(118); NCover.NCoverCheck.Add(117); NCover.NCoverCheck.Add(116); NCover.NCoverCheck.Add(116); NCover.NCoverCheck.Add(118); NCover.NCoverCheck.Add(117); NCover.NCoverCheck.Add(117); NCover.NCoverCheck.Add(117); NCover.NCoverCheck.Add(117); NCover.NCoverCheck.Add(117); NCover.NCoverCheck.Add(117); NCover.NCoverCheck.Add(117); return (decimal)HitCoveragePoints / (decimal)TotalCoveragePoints;
			}
		}

		[XmlIgnore]
		public CoverageNamespace DefaultNamespace;

		/// <summary>
		/// The setter is required only for historical deserialisation of coverage report.
		/// </summary>
		public CoverageNamespace[] FlattenedNamespaces
		{
			get 
			{
				ArrayList list = new ArrayList();

				Walk(list, DefaultNamespace);

				NCover.NCoverCheck.Add(119); NCover.NCoverCheck.Add(118); NCover.NCoverCheck.Add(119); NCover.NCoverCheck.Add(118); NCover.NCoverCheck.Add(117); NCover.NCoverCheck.Add(117); NCover.NCoverCheck.Add(119); NCover.NCoverCheck.Add(118); NCover.NCoverCheck.Add(118); NCover.NCoverCheck.Add(118); NCover.NCoverCheck.Add(118); NCover.NCoverCheck.Add(118); NCover.NCoverCheck.Add(118); NCover.NCoverCheck.Add(118); return (CoverageNamespace[]) list.ToArray(typeof(CoverageNamespace));
			}
			set
			{				
				DefaultNamespace = new CoverageNamespace();
			
				NCover.NCoverCheck.Add(120); NCover.NCoverCheck.Add(119); NCover.NCoverCheck.Add(120); NCover.NCoverCheck.Add(119); NCover.NCoverCheck.Add(118); NCover.NCoverCheck.Add(118); NCover.NCoverCheck.Add(120); NCover.NCoverCheck.Add(119); NCover.NCoverCheck.Add(119); NCover.NCoverCheck.Add(119); NCover.NCoverCheck.Add(119); NCover.NCoverCheck.Add(119); NCover.NCoverCheck.Add(119); NCover.NCoverCheck.Add(119); foreach (CoverageNamespace cNamespace in value)
				{
					CoverageNamespace ns = DefaultNamespace.GetNamespace(cNamespace.Namespace.Split('.'));
					NCover.NCoverCheck.Add(121); NCover.NCoverCheck.Add(120); NCover.NCoverCheck.Add(121); NCover.NCoverCheck.Add(120); NCover.NCoverCheck.Add(119); NCover.NCoverCheck.Add(119); NCover.NCoverCheck.Add(121); NCover.NCoverCheck.Add(120); NCover.NCoverCheck.Add(120); NCover.NCoverCheck.Add(120); NCover.NCoverCheck.Add(120); NCover.NCoverCheck.Add(120); NCover.NCoverCheck.Add(120); NCover.NCoverCheck.Add(120); foreach (CoverageFile cFile in cNamespace.Members)
					{
						ns.Members.Add(cFile);
					}
				}
			}
		}

		private void Walk(ArrayList list, CoverageNamespace aNamespace)
		{
			if (aNamespace.Members.Count > 0 && NCover.NCoverCheck.Add(127) && NCover.NCoverCheck.Add(126) && NCover.NCoverCheck.Add(127) && NCover.NCoverCheck.Add(126) && NCover.NCoverCheck.Add(125) && NCover.NCoverCheck.Add(125) && NCover.NCoverCheck.Add(127) && NCover.NCoverCheck.Add(126) && NCover.NCoverCheck.Add(126) && NCover.NCoverCheck.Add(126) && NCover.NCoverCheck.Add(126) && NCover.NCoverCheck.Add(126) && NCover.NCoverCheck.Add(126) && NCover.NCoverCheck.Add(126))
			{
				list.Add(aNamespace);
			}
			NCover.NCoverCheck.Add(122); NCover.NCoverCheck.Add(121); NCover.NCoverCheck.Add(122); NCover.NCoverCheck.Add(121); NCover.NCoverCheck.Add(120); NCover.NCoverCheck.Add(120); NCover.NCoverCheck.Add(122); NCover.NCoverCheck.Add(121); NCover.NCoverCheck.Add(121); NCover.NCoverCheck.Add(121); NCover.NCoverCheck.Add(121); NCover.NCoverCheck.Add(121); NCover.NCoverCheck.Add(121); NCover.NCoverCheck.Add(121); foreach (CoverageNamespace childNs in aNamespace.ChildNamespaces)
			{
				Walk(list, childNs);
			}
		}
	}
}














